package drds.global_transaction.api.message_codec.request_and_response.transaction.global_transaction.branch_transaction_status_report;

import java.nio.ByteBuffer;

import drds.global_transaction.api.api.BranchTransactionStatus;
import drds.global_transaction.api.api.RpcContext;
import drds.global_transaction.api.message_codec.IMergedMessage;
import drds.global_transaction.api.message_codec.request_and_response.transaction.TransactionResponse;
import drds.global_transaction.api.message_codec.request_and_response.transaction.global_transaction.GlobalTransactionRequestMessage;
import lombok.Getter;
import lombok.Setter;

public class BranchTransactionStatusReportRequestMessage extends GlobalTransactionRequestMessage implements IMergedMessage
{
	private static final long serialVersionUID = 1L;

	/**
	 * 需要结合当前的地址和端口 才是一个完整的全局事务ID
	 */
	@Setter
	@Getter
	private long globaltransactionId;
	@Setter
	@Getter
	private long branchTransactionId;
	@Setter
	@Getter
	private String resourceId;
	@Setter
	@Getter
	private BranchTransactionStatus status;
	@Setter
	@Getter
	private String applicationData;

	@Override
	public short getTypeCode()
	{
		return branch_transaction_status_report_request_message;
	}

	@Override
	public byte[] encode()
	{
		byte[] applicationDataBytes = null;
		if (this.applicationData != null)
		{
			applicationDataBytes = applicationData.getBytes(UTF8);
			if (applicationDataBytes.length > 512)
			{
				byteBuffer = ByteBuffer.allocate(applicationDataBytes.length + 1024);
			}
		}

		// 1. Transaction Id
		byteBuffer.putLong(this.globaltransactionId);
		// 2. Branch Id
		byteBuffer.putLong(this.branchTransactionId);
		// 3. Branch Status
		byteBuffer.put((byte) this.status.ordinal());
		// 4. Resource Id
		if (this.resourceId != null)
		{
			byte[] bs = resourceId.getBytes(UTF8);
			byteBuffer.putShort((short) bs.length);
			if (bs.length > 0)
			{
				byteBuffer.put(bs);
			}
		} else
		{
			byteBuffer.putShort((short) 0);
		}

		// 5. Application Data
		if (this.applicationData != null)
		{
			byteBuffer.putInt(applicationDataBytes.length);
			if (applicationDataBytes.length > 0)
			{
				byteBuffer.put(applicationDataBytes);
			}
		} else
		{
			byteBuffer.putInt(0);
		}

		byteBuffer.flip();
		byte[] content = new byte[byteBuffer.limit()];
		byteBuffer.get(content);
		return content;
	}

	@Override
	public void decode(ByteBuffer byteBuffer)
	{
		this.globaltransactionId = byteBuffer.getLong();
		this.branchTransactionId = byteBuffer.getLong();
		this.status = BranchTransactionStatus.get(byteBuffer.get());
		short len = byteBuffer.getShort();
		if (len > 0)
		{
			byte[] bs = new byte[len];
			byteBuffer.get(bs);
			this.resourceId = new String(bs, UTF8);
		}

		int iLen = byteBuffer.getInt();
		if (iLen > 0)
		{
			byte[] bs = new byte[iLen];
			byteBuffer.get(bs);
			this.applicationData = new String(bs, UTF8);
		}
	}

	@Override
	public TransactionResponse handle(RpcContext rpcContext)
	{
		return transactionCoordinatorInboundHandler.handle(rpcContext, this);
	}
}
